package com.td.module.produce.service.husbandry;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.td.framework.common.pojo.PageResult;
import com.td.framework.common.util.collection.CollectionUtils;
import com.td.module.agro.convert.input.InputConvert;
import com.td.module.agro.dal.dataobject.input.InputDO;
import com.td.module.agro.dal.mysql.input.InputMapper;
import com.td.module.produce.controller.admin.husbandry.vo.HusbandryCreateReqVO;
import com.td.module.produce.controller.admin.husbandry.vo.HusbandryExportReqVO;
import com.td.module.produce.controller.admin.husbandry.vo.HusbandryPageReqVO;
import com.td.module.produce.controller.admin.husbandry.vo.HusbandryUpdateReqVO;
import com.td.module.produce.convert.husbandry.HusbandryConvert;
import com.td.module.produce.dal.dataobject.husbandry.HusbandryDO;
import com.td.module.produce.dal.dataobject.inputhusbandry.InputHusbandryDO;
import com.td.module.produce.dal.mysql.husbandry.HusbandryMapper;
import com.td.module.produce.dal.mysql.inputhusbandry.InputHusbandryMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;

import static com.td.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.td.module.produce.enums.ErrorCodeConstants.HUSBANDRY_NOT_EXISTS;

/**
 * 生产管理农事 Service 实现类
 *
 * @author 吴佰强
 */
@Service
@Validated
public class HusbandryServiceImpl implements HusbandryService {

    @Resource
    private HusbandryMapper husbandryMapper;

    @Resource
    private InputMapper inputMapper;

    @Resource
    private InputHusbandryMapper inputHusbandryMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long createHusbandry(HusbandryCreateReqVO createReqVO) {
        // 插入
        HusbandryDO husbandry = HusbandryConvert.INSTANCE.convert(createReqVO);
        husbandryMapper.insert(husbandry);
        //插入投入品
        if (!CollectionUtils.isAnyEmpty(createReqVO.getInputCreateReqVOS())) {
            List<InputDO> inputDOS = InputConvert.INSTANCE.convertBatch(createReqVO.getInputCreateReqVOS());
            inputMapper.insertBatch(inputDOS);
            //插入中间表
            inputDOS.stream().map(InputDO::getId).collect(Collectors.toList()).forEach(inputId -> {
                InputHusbandryDO inputHusbandryDO = new InputHusbandryDO();
                inputHusbandryDO.setHusbandryId(husbandry.getId());
                inputHusbandryDO.setInputId(inputId);
                inputHusbandryMapper.insert(inputHusbandryDO);
            });
        }
        // 返回
        return husbandry.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateHusbandry(HusbandryUpdateReqVO updateReqVO) {
        // 校验存在
        this.validateHusbandryExists(updateReqVO.getId());
        // 更新
        HusbandryDO updateObj = HusbandryConvert.INSTANCE.convert(updateReqVO);
        husbandryMapper.updateById(updateObj);

        //更新投入品
        if (!CollectionUtils.isAnyEmpty(updateReqVO.getInputUpdateReqVOS())) {
            List<InputDO> inputDOS = InputConvert.INSTANCE.convertBatchUpdate(updateReqVO.getInputUpdateReqVOS());
            inputDOS.forEach(inputDO -> {
                inputMapper.deleteById(inputDO);
                inputDO.setId(null);
                inputMapper.insert(inputDO);
            });
            //更新中间表
            inputHusbandryMapper.delete(new QueryWrapper<InputHusbandryDO>().eq("husbandry_id", updateObj.getId()));
            inputDOS.stream().map(InputDO::getId).collect(Collectors.toList()).forEach(inputId -> {
                InputHusbandryDO inputHusbandryDO = new InputHusbandryDO();
                inputHusbandryDO.setHusbandryId(updateObj.getId());
                inputHusbandryDO.setInputId(inputId);
                inputHusbandryMapper.insert(inputHusbandryDO);
            });
        }
    }

    @Override
    public void deleteHusbandry(Long id) {
        // 校验存在
        this.validateHusbandryExists(id);
        // 删除
        husbandryMapper.deleteById(id);
        //查找中间表投入品
        List<InputHusbandryDO> inputHusbandryDOS = inputHusbandryMapper.selectList(new QueryWrapper<InputHusbandryDO>().eq("husbandry_id", id));
        if (!CollectionUtils.isAnyEmpty(inputHusbandryDOS)) {
            //迭代删除投入品
            inputHusbandryDOS.forEach(inputHusbandryDO -> inputMapper.deleteById(inputHusbandryDO.getInputId()));
        }
    }

    private void validateHusbandryExists(Long id) {
        if (husbandryMapper.selectById(id) == null) {
            throw exception(HUSBANDRY_NOT_EXISTS);
        }
    }

    @Override
    public HusbandryUpdateReqVO getHusbandry(Long id) {
        HusbandryUpdateReqVO updateReqVO = new HusbandryUpdateReqVO();
        BeanUtils.copyProperties(husbandryMapper.selectById(id), updateReqVO);
        List<Long> inputIds = inputHusbandryMapper.
                selectList(new QueryWrapper<InputHusbandryDO>().eq("husbandry_id", id)).stream().
                map(InputHusbandryDO::getInputId).collect(Collectors.toList());
        if (!CollectionUtils.isAnyEmpty(inputIds)) {
            updateReqVO.setInputUpdateReqVOS(
                    InputConvert.INSTANCE.convertBatchUpdate02(inputMapper.selectBatchIds(inputIds)));
        }
        return updateReqVO;
    }

    @Override
    public List<HusbandryDO> getHusbandryList(Collection<Long> ids) {
        return husbandryMapper.selectBatchIds(ids);
    }

    @Override
    public PageResult<HusbandryDO> getHusbandryPage(HusbandryPageReqVO pageReqVO) {
        return husbandryMapper.selectPage(pageReqVO);
    }

    @Override
    public List<HusbandryDO> getHusbandryList(HusbandryExportReqVO exportReqVO) {
        return husbandryMapper.selectList(exportReqVO);
    }

    @Override
    public List<HusbandryDO> getHusbandryListByInfoId(Long infoId) {
        return husbandryMapper.selectList(new QueryWrapper<HusbandryDO>().eq("info_id", infoId));
    }

}
